/*  File Name	: SockAcceptor.cpp
 *  Author		: Pang Jiacai
 *	 E-mail		: 823960168@qq.com
 *  Created on	: 2012-4-20
 *  Description:
 */

#include "SockAcceptor.h"
#include "EventHandler.h"

SockAcceptor::SockAcceptor()
{

}

SockAcceptor::~SockAcceptor()
{

}

int SockAcceptor::open(int port,std::string ip,int pro_family,
		int type,int protocol,bool reuseaddr,int backlog)
{
	if(Sock::open(pro_family,type,protocol,reuseaddr)!=0)
	{
		return -1;
	}

	struct sockaddr_in server_addr;
	bzero(&server_addr, sizeof(server_addr));
	if (ip.empty())
	{
		server_addr.sin_addr.s_addr = INADDR_ANY;
	}
	else
	{
		server_addr.sin_addr.s_addr = inet_addr(ip.c_str());
	}
	server_addr.sin_port = htons(port);
	server_addr.sin_family = pro_family;

	int ret = ::bind(this->get_handle(),(sockaddr*) &server_addr,sizeof(struct sockaddr));
	if (ret < 0)
	{
		LOG((DEBUG_LOG,"SockAcceptor::open bind() error:[port:%d %s]",
				port,strerror(errno)));
		::close(this->get_handle());
		return -1;
	}

	ret = ::listen(this->get_handle(), backlog);
	if (ret < 0)
	{
		::close(this->get_handle());
		LOG((DEBUG_LOG,"SockAcceptor::open listen() error:%s",strerror(errno)));
		return -1;
	}
	LOG((DEBUG_LOG,"Listening port:%d",port));
	return 0;
}

int SockAcceptor::close(void)
{
	return Sock::close();
}

int SockAcceptor::accept(SockStream *peer,sockaddr *addr)
{
	if(NULL==peer)
	{
		return -1;
	}

	socklen_t len = 0;
	int accept_fd = ::accept(this->get_handle(),addr,&len);
	peer->set_handle(accept_fd);
	if(peer->get_handle()==INVALID_HANDLER)
	{
		peer->close();
		return -1;
	}

	return 0;
}
